package com.hfut.eeg.common.util;

import cn.hutool.core.lang.Console;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hfut.eeg.common.component.EEGfileListener;
import com.hfut.eeg.dto.EEG;
import com.hfut.eeg.dto.EEGTrans;
import com.hfut.eeg.dto.EerWaves;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.sql.Blob;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @author 梁琦
 * @program: eeg
 * @Package com.hfut.eeg.common.util
 * @Description: 实现List与blob类型的互换
 * @date 2019-11-22 14:43
 */
public class BlobListTrans {
    private static final Logger LOGGER = LoggerFactory.getLogger(BlobListTrans.class);

    /**
    * @Description: 将数组转化为blob对象
    * @param list 数组
    * @return byte[] 字节数组
    * @author 梁琦
    * @date 2019-12-30 19:52
    * @throws
    */
    public static byte[] list2Blob(List list) {
        byte [] bytes = null;
        try (ByteArrayOutputStream out = new ByteArrayOutputStream();
             ObjectOutputStream outputStream = new ObjectOutputStream(out)) {
            outputStream.writeObject(list);
            bytes  =  out.toByteArray();
            return  bytes;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bytes;
    }

    /**
    * @Description: 将字节数组装换为数组
    * @param b 字节数组
    * @return  List<Object> 数组
    * @author 梁琦
    * @date 2019-12-30 19:53
    * @throws
    */
    public static List<Object> blob2List(byte[] b){
        List<Object> list = new ArrayList<>();
        b = b==null?new byte[0]:b;
        try(ObjectInputStream in  = new ObjectInputStream(new ByteArrayInputStream(b))) {
            list= (List<Object>)in.readObject();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
    * @Description: 将EEGTrans类型或EEG数据转换为二位数组
    * @param trans 类EEGTrans对象
    * @return ArrayList<ArrayList>二维数组
    * @author 梁琦
    * @date 2019-12-30 19:53
    * @throws
    */
    public static ArrayList<ArrayList> transEEGTransToList(Object trans){
        if(trans==null){
            return null;
        }
        ArrayList<ArrayList> result = new ArrayList<>();
        ArrayList<String> fields = getEEGFields(trans);
        for (String field : fields) {
            try {
                byte[] bytes = (byte[]) trans.getClass().getMethod("get" + field, null).invoke(trans);
                result.add((ArrayList) blob2List(bytes));
            } catch (IllegalAccessException
                    | InvocationTargetException
                    | NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
    * @Description: 将二维数组转换为EEG类型数据
    * @param lists 二维数组 c EEG类型
    * @return Object EEG类型
    * @author 梁琦
    * @date 2019-12-30 19:53
    * @throws
    */
    public static Object transArrToEEG(ArrayList<ArrayList> lists,Object c){
        if(lists==null){
            return null;
        }
        ArrayList<String> fields = getEEGFields(c);
        if(lists.size() != fields.size()){
            LOGGER.error("将二维数组转换为EEG类型数据时数据大小不匹配");
            return null;
        }
        for (int i=0;i<fields.size();i++) {
            byte[] bytes = BlobListTrans.list2Blob(lists.get(i));
            try {
                c.getClass().getMethod("set" + fields.get(i),byte[].class).invoke(c,bytes);
            } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
        return c;
    }

    /**
    * @Description: 获取Object中某些属性
    * @param Object 对象
    * @return ArrayList<String> 属性数组
    * @author 梁琦
    * @date 2019-12-30 19:54
    * @throws
    */
    public static ArrayList<String> getEEGFields(Object o){
        ArrayList<String> result = new ArrayList<>();
        Field[] fields = o.getClass().getDeclaredFields();
        for (Field field:fields){
            if(!field.getType().isAssignableFrom(Long.class)
                    && !field.getType().isAssignableFrom(Integer.class)
                    && !field.getType().isAssignableFrom(String.class)){
                result.add(field.getName());
            }
        }
        return result;
    }

}
